package test.crane;

import java.math.*;

import ptolemy.actor.*;
import ptolemy.kernel.*;
import ptolemy.kernel.util.*;
import ptolemy.data.*;
import ptolemy.data.type.*;
import ptolemy.math.Utilities;

//////////////////////////////////////////////////////////////////////////
//// LoadPosReached
/**

@author Ivan Jeukens
@version v 0.1 07/02/2002
*/
public class LoadPosReached extends TypedAtomicActor {

    public LoadPosReached(CompositeEntity container, String name) throws
            IllegalActionException, NameDuplicationException {
        super(container, name);

        shutdown = new TypedIOPort(this, "shutdown", true, false);
        shutdown.setTypeEquals(BaseType.GENERAL);

        emstop_input = new TypedIOPort(this, "emstop_input", true, false);
        emstop_input.setTypeEquals(BaseType.GENERAL);

        trigger = new TypedIOPort(this, "trigger", true, false);
        trigger.setTypeEquals(BaseType.GENERAL);

        posdesired = new TypedIOPort(this, "posdesired", true, false);
        posdesired.setTypeEquals(BaseType.DOUBLE);

        xl = new TypedIOPort(this, "xl", true, false);
        xl.setTypeEquals(BaseType.DOUBLE);

        brake = new TypedIOPort(this, "brake", false, true);
        brake.setTypeEquals(BaseType.BOOLEAN);

        new Attribute(this, "_nonStrictMarker");
    }

    public TypedIOPort trigger;
    public TypedIOPort shutdown;
    public TypedIOPort emstop_input;

    public TypedIOPort posdesired;
    public TypedIOPort xl;

    public TypedIOPort brake;

    ///////////////////////////////////////////////////////////////////
    ////                         public methods                    ////

    public void pruneDependencies() {
        super.pruneDependencies();

        removeDependency(trigger, brake);
        removeDependency(shutdown, brake);
        removeDependency(emstop_input, brake);
    }

    public void initialize() throws IllegalActionException  {
        super.initialize();
        _reset();
    }
    
    public void fire() throws IllegalActionException {

        if(_state == RUNNING) {
            if(posdesired.isKnown() && xl.isKnown() && !brake.isKnown()) {
            //if(posdesired.isKnown() && xl.isKnown()) {
                if(posdesired.hasToken(0)) {
                    _posdesired = ((DoubleToken)posdesired.get(0)).doubleValue();
                    System.out.println("Load Reached - Pos desired = " + _posdesired);
                }

                if(xl.hasToken(0) && _posdesired != -10) {
                    double pos = ((DoubleToken)xl.get(0)).doubleValue();
                    if((pos >= _posdesired - 0.01) && (pos <= _posdesired + 0.01)) {
                        System.out.println("CHEGUEI!!!..." + pos + " desired -> " +
                            _posdesired);
                        brake.broadcast(new BooleanToken(true));
                        _posdesired = -10;
                    }
                }
            }
        }

        if(posdesired.isKnown() && xl.isKnown() && !brake.isKnown()) {
            brake.broadcastClear();
        }
    }

    public boolean postfire() throws IllegalActionException {
        switch(_state) {
            case READY : {
                if(trigger.hasToken(0) && !shutdown.hasToken(0)) {
                    _state = RUNNING;
                }
            } break;

            case RUNNING: {
                if(shutdown.isKnown()) {
                    if(shutdown.hasToken(0)) {
                        _reset();
                        break;
                    }
                }

                if(emstop_input.isKnown()) {
                    if(emstop_input.hasToken(0)) {
                        _reset();
                        break;
                    }
                }
            } break;
        }
        return true;
    }

    ///////////////////////////////////////////////////////////////////
    ////                        private methods                    ////

    private void _reset() {
        _state = READY;
        _posdesired = -10.0;
    }

    ///////////////////////////////////////////////////////////////////
    ////                      private variables                    ////

    private int _state;

    private double _posdesired = 0.0;

    private static final int READY = 1;
    private static final int RUNNING = 2;
}
